#ifndef __STRING_UTIL_H_
#define __STRING_UTIL_H_

#include <vector>
#include <string>
#include <iostream>
#include "base/nocopyable.h"


namespace tb
{
using std::string;

class StringUtil : public nocopyable
{
public:
    static void split(const string& str, std::vector<string>& v, const char* delimiter = "|");
    //根据第一个delimiter指定的字符串，将str切割成两半
    static void cut(const string& str, std::vector<string>& v, const char* delimiter = "|");
    static string& replace(string& str, const string& toReplaced, const string& newStr);

    // 去掉最左边所有指定的字符（默认空格）
    static string lstrip(const string& str, char stripmed = ' ');
    // 去掉最右边所有指定的字符（默认空格）
    static string rstrip(const string& str, char stripmed = ' ');
    // 去掉左右两边所有指定的字符（默认空格）
    static string strip(const string& str, char stripmed = ' ');
    
    // 去掉最左边的字符串
    static string lstrip(const string& str, const string& sub_str);
    // 去掉最右边的字符串
    static string rstrip(const string& str, const string& sub_str);
    // 去掉两边的字符串
    static string strip(const string& str, const string& sub_str);

    // 将字符串全部转化为小写
    static string upper_string(const string& str);
    // 将字符串全部转化为大写
    static string lower_string(const string& str);

    // 计算字符数组中保护字符串的个数
    static int count_of_substr(const char *str, const string& sub_str);
    // 计算字符串中保护字符串的个数
    static int count_of_substr(const string& str, const string& sub_str);
};



void StringUtil::split(const string& str, std::vector<string>& v, const char* delimiter/* = "|"*/)
{
    if (delimiter == NULL || str.empty())
        return;

    string buf(str);
    size_t pos = string::npos;
    string substr;
    int delimiterlength = strlen(delimiter);
    while (true)
    {
        pos = buf.find(delimiter);
        if (pos != string::npos)
        {
            substr = buf.substr(0, pos);
            if (!substr.empty())
                v.push_back(substr);

            buf = buf.substr(pos + delimiterlength);
        }
        else
        {
            if (!buf.empty())
                v.push_back(buf);
            break;
        }
    }
}

void StringUtil::cut(const string& str, std::vector<string>& v, const char* delimiter/* = "|"*/)
{
    if (delimiter == NULL || str.empty())
        return;

    string buf(str);
    int delimiterlength = strlen(delimiter);
    size_t pos = buf.find(delimiter);
    if (pos == string::npos)
        return;

    string substr1 = buf.substr(0, pos);
    string substr2 = buf.substr(pos + delimiterlength);
    if (!substr1.empty())
        v.push_back(substr1);

    if (!substr2.empty())
        v.push_back(substr2);
}

string& StringUtil::replace(string& str, const string& toReplaced, const string& newStr)
{
    if (toReplaced.empty() || newStr.empty())
        return str;

    for (string::size_type pos = 0; pos != string::npos; pos += newStr.length())
    {
        pos = str.find(toReplaced, pos);
        if (pos != string::npos)
            str.replace(pos, toReplaced.length(), newStr);
        else
            break;
    }

    return str;
}

string StringUtil::lstrip(const string& str, char stripmed/* = ' '*/)
{
    string tmp;
    size_t length = str.length();
    for (size_t i = 0; i < length; ++i)
    {
        if (str[i] != stripmed)
        {
            tmp = str.substr(i);
            break;
        }
    }
    return tmp;
}

string StringUtil::rstrip(const string& str, char stripmed/* = ' '*/)
{
    string tmp;
    size_t length = str.length();
    for (size_t i = length - 1; i >= 0; --i)
    {
        if (str[i] != stripmed)
        {
            tmp = str.substr(0, i + 1);
            break;
        }
    }
    return tmp;
}

string StringUtil::lstrip(const string& str, const string& sub_str)
{
    size_t len = sub_str.size();
    string::size_type i = 0;
 
    i = str.find(sub_str, i);
    int count = 0;
    if(i == 0)
    {
        count = 1;
        while((i = str.find(sub_str, i+len)) != string::npos)
        {
            if(i != len*count)
                break;
            count++;
        }
    }
    else
    {
        return str;
    }
 
    return str.substr(len*count);
}
 
string StringUtil::rstrip(const string& str, const string& sub_str)
{
    int sub_len = sub_str.size();
    int last_index = str.size()-1;
    for(int i = last_index; i >= 0; i -= sub_len)
    {
        int flag = 0;
        for(int j = 0; j < i && j < sub_len; j++)
        {
            if(sub_str[j] != str[i + 1 - sub_len + j])
            {
                flag = 1;
                break;
            }
        }
        
        if(flag == 1)
        {
            break;
        }
        else
        {
            last_index = i - sub_len;
        }
    }
 
    return str.substr(0, last_index+1);
}
 
string StringUtil::strip(const string& str, const string& sub_str)
{
    return lstrip(rstrip(str, sub_str), sub_str);
}


string StringUtil::strip(const string& str, char stripmed/* = ' '*/)
{
    return lstrip(rstrip(str, stripmed), stripmed);
}

string StringUtil::upper_string(const string& str)
{
    string upper_str = str;
    size_t len = str.size();
    for(size_t i = 0; i < len; i++)
    {
        if(str[i] >= 'a' && str[i] <= 'z')
            upper_str[i] -= 32;
    }
 
    return upper_str;
}

string StringUtil::lower_string(const string& str)
{
    string lower_str = str;
    size_t len = str.size();
    for(size_t i = 0; i < len; i++)
    {
        if(str[i] >= 'A' && str[i] <= 'Z')
            lower_str[i] += 32;
    }
 
    return lower_str;
}

int StringUtil::count_of_substr(const string& str, const string& sub_str)
{
    int count = 0;
    size_t len = sub_str.size();
    string::size_type i = 0;
    while((i = str.find(sub_str, i))!= string::npos)
    {
        count++;
        i += len;
    }
    
    return count;
}

int StringUtil::count_of_substr(const char *str, const string& sub_str)
{
    int count = 0;
    size_t len = sub_str.size();
    const char *p = sub_str.c_str();
    const char *index = str;
    while(NULL != (index = strstr(index, p)))
    {
        count++;
        index += len;
    }
 
    return count;
}

}   // namespace tb

#endif
